#include "H264_decoder.h"
#include <QDebug>



// H264_Decoder::H264_Decoder(AVContext *avc, QObjectList *parent):
//     QThread(parent),
//     avContxt_(avc)
// {

//     yuv_frame_ = AVFramePtr(av_frame_alloc(),[](AVFrame* p){av_frame_free(&p);});
// }

H264_Decoder::H264_Decoder(AVContext *acv, QObject *parent):
    QThread(parent),
    avContxt_(acv)
{
    yuv_frame_ = AVFramePtr(av_frame_alloc(),[](AVFrame* p){av_frame_free(&p);});
}

H264_Decoder::~H264_Decoder()
{
    //释放资源
    Close();
}

int H264_Decoder::Open(AVCodecParameters *codecParamer)
{
    //初始化解码器
    if(codec_ || codecContext_)
    {
        return -1;
    }
    //创建解码器
        codec_ = const_cast<AVCodec*>(avcodec_find_encoder(codecParamer->codec_id));
    if(!codec_)
        {
            qDebug() <<"avcodec_find_decoder failed";
        }

    codecContext_ = avcodec_alloc_context3(codec_);
        //复制解码器参数
    if(avcodec_parameters_to_context(codecContext_,codecParamer) <0)
    {
        qDebug() << "avcodec_parameters_to_ context failed";
        return -1;
    }
    //加速解码属性
    codecContext_->flags |=AV_CODEC_FLAG2_FAST;

    //更新当前音视频剩下参数
    avContxt_->width = codecContext_->width;
    avContxt_->height = codecContext_->height;
    avContxt_->vidio_fmt = AV_PIX_FMT_YUV420P;

    //启动线程开始解码
    start();
    return 0;
}

void H264_Decoder::Close()
{
    quit_= true;
    if(isRunning())
    {
        this->quit();
        this->wait();
    }
}

void H264_Decoder::run()
{
    //解码线程
    //需要准备编码数据
    AVPacketPtr pkt = nullptr;
    while (!quit_)
    {
        //编码数据怎么来
        if(!video_queue_.size())//0false > 0 true
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
            continue;
        }
        //取出编码数据
        video_queue_.pop(pkt);
        //开始解码数据 发送编码数据
        if(avcodec_send_packet(codecContext_,pkt.get()))
        {
            break;
        }
        int ret = 0;
        //接收帧
        while(ret >= 0)
        {
            ret = avcodec_receive_frame(codecContext_,yuv_frame_.get());
            if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            {
                break;
            }
            //解码成功
            //视频格式转换
            //推送到
            avContxt_->video_queue.push(yuv_frame_);
        }
    }
}
